package com.gf.forcesystem.mq;

import com.gf.forcesystem.config.CotaskingRabbitmqConfig;
import com.gf.forcesystem.model.dto.weather.*;
import com.gf.forcesystem.api.WeatherService;
import com.gf.forcesystem.mq.weatherparse.IWeatherParse;
import com.gf.framework.common.utils.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.C;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * @author gaofei
 * @date 2022/6/19 16:57
 * 天气信息处理
 */
@Component
@Slf4j
public class WeatherMqReciver implements SmartInitializingSingleton {
    @Resource
    private List<WeatherService> weatherServices;

    /**
     * 天气转换器map
     */
    private final Map<Byte, IWeatherParse> iWeatherParseMap = new HashMap<>();

    /**
     * 接收天气状态帧信息
     * @param data
     */
    @RabbitListener(queues = CotaskingRabbitmqConfig.weatherQueue)
    @RabbitHandler
    public void recv(byte[] data) {
        if (data.length != 11) {
            return;
        }

        ByteBuffer byteBuffer = ByteBuffer.wrap(data);
        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
        byteBuffer.get();
        byteBuffer.get();
        byteBuffer.getShort();
        byte identifier = byteBuffer.get();

        IWeatherParse iWeatherParse = iWeatherParseMap.get(identifier);
        if (iWeatherParse == null) {
            return;
        }

        AbstractWeather abstractWeather = iWeatherParse.parse(byteBuffer);
        if (abstractWeather == null) {
            return;
        }
        deal(abstractWeather);
    }


    /**
     * 处理天气信息
     * @param weather
     */
    private void deal(AbstractWeather weather) {
        if (CollectionUtils.isEmpty(weatherServices))
            return;

        for (WeatherService weatherService : weatherServices) {
            try {
                weatherService.deal(weather);
            } catch (Exception e) {
                log.error("{} 处理模型状态帧出错 {} {}", weatherService.getClass().getName(), weather.getClass().getSimpleName(), weather, e);
            }
        }
    }

    /**
     * 加载天气解码器
     */
    @Override
    public void afterSingletonsInstantiated() {
        Map<String, IWeatherParse> weatherParseMap = SpringContextUtil.getBeanMap(IWeatherParse.class);
        weatherParseMap.values().forEach(iWeatherParse -> {
            log.info("加载天气解码器: {}", iWeatherParse.getClass().getName());
            iWeatherParseMap.put(iWeatherParse.identifier(), iWeatherParse);
        });
    }
}
